
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "reflecxx.h"

enum my_enum_t {
    ME_ZERO,
    ME_ONE,
};

struct my_inner {
    int mi_one;
    float mi_two;
    uint64_t mi_three;
};

struct my_outer {
    enum my_enum_t mo_enum;
    int mo_int;
    char *mo_str;
    struct my_inner mo_struct;
    struct {
	int ma_shy;
    } mo_anon;
    struct my_outer *mo_link;
};

extern struct reflecxx_full_type my_outer_type_info;

int main(int argc, char *argv[])
{
    char *expected_fmt =
	"{\"mo_enum\":\"ME_ONE\", \"mo_int\":128, "
	"\"mo_str\":\"Hello, World!\", "
	"\"mo_struct\":{\"mi_one\":16, \"mi_two\":3.140000, \"mi_three\":6976}"
	", \"mo_anon\":{\"ma_shy\":25}, "
	"\"mo_link\":}";
    struct my_outer mo_link = { 0 };
    struct my_outer mo = {
	ME_ONE,
	128,
	"Hello, World!",
	{ 16, 3.14, 6976 },
	{ 25 },
	&mo_link
    };

    int retval = EXIT_SUCCESS;
    reflecxx_primitive_t rp;
    char expected[1024];
    char buffer[1024];
    char *abuf;

    snprintf(expected, sizeof(expected), expected_fmt, &mo_link);

    reflecxx_print(buffer, sizeof(buffer), &my_outer_type_info, &mo);
    assert(strcmp(buffer, expected) == 0);
    abuf = reflecxx_aprint(&my_outer_type_info, &mo);
    assert(abuf != NULL);
    assert(strcmp(abuf, expected) == 0);
    reflecxx_free(abuf);

    assert(reflecxx_print(buffer, 32, &my_outer_type_info, &mo) == 0);
    
    return retval;
}
